home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
os2
/
radius_2.zip
/
radiusd.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-04
|
46KB
|
1,814 lines
/*
*
* RADIUS
* Remote Authentication Dial In User Service
*
*
* Livingston Enterprises, Inc.
* 6920 Koll Center Parkway
* Pleasanton, CA 94566
*
* Copyright 1992 Livingston Enterprises, Inc.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose and without fee is hereby granted, provided that this
* copyright and permission notice appear on all copies and supporting
* documentation, the name of Livingston Enterprises, Inc. not be used
* in advertising or publicity pertaining to distribution of the
* program without specific prior permission, and notice be given
* in supporting documentation that copying and distribution is by
* permission of Livingston Enterprises, Inc.
*
* Livingston Enterprises, Inc. makes no representations about
* the suitability of this software for any purpose. It is
* provided "as is" without express or implied warranty.
*
*/
/* don't look here for the version, run radiusd -v or look in version.c */
static char sccsid[] =
"@(#)radiusd.c 1.17 Copyright 1992 Livingston Enterprises Inc";
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <fcntl.h>
#include <pwd.h>
#include <time.h>
#include <ctype.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <process.h>
#include <sys/wait.h>
#include <io.h>
#if !defined(NOSHADOW)
/*#include <shadow.h>*/
#endif /* !NOSHADOW */
#include "radius.h"
char recv_buffer[4096];
char send_buffer[4096];
char *progname;
int sockfd;
int acctfd;
int debug_flag;
int spawn_flag;
int acct_flag;
int acct_pid;
char *radius_dir;
char *radacct_dir;
#ifdef OS2
char radius_dir_hold[256];
char radacct_dir_hold[256];
#endif
UINT4 expiration_seconds;
UINT4 warning_seconds;
int errno;
static AUTH_REQ *first_request;
void sig_fatal();
void sig_hup();
void sig_cleanup();
void rad_passchange();
void usage(void);
int config_init();
int radrespond(AUTH_REQ *authreq,int activefd);
int rad_spawn_child(AUTH_REQ *authreq,int activefd);
void rad_authenticate(AUTH_REQ *authreq,int activefd);
void send_reject(AUTH_REQ *authreq,char *msg,int activefd);
int set_expiration(VALUE_PAIR *user_check,UINT4 expiration);
void send_pwack(AUTH_REQ *authreq,int activefd);
int calc_digest(u_char *digest,AUTH_REQ *authreq);
int pw_expired(UINT4 exptime);
void send_challenge(AUTH_REQ *authreq,char *msg,char *state,int activefd);
int unix_pass(char *name,char *passwd);
void send_accept(AUTH_REQ *authreq,VALUE_PAIR *reply,char *msg,int activefd);
int
main(argc, argv)
int argc;
char **argv;
{
int salen;
int result;
struct sockaddr salocal;
struct sockaddr saremote;
struct sockaddr_in *sin;
struct servent *svp;
u_short lport;
AUTH_REQ *authreq;
AUTH_REQ *radrecv();
char argval;
int t;
#ifndef OS2
int pid;
#else
char work_dir[256];
#endif
int cons;
fd_set readfds;
int status;
char *nargv[20];
for ( t=0;t<argc ;t++ )
nargv[t] = argv[t];
nargv[t++]="-i";
nargv[t]=NULL;
progname = *argv++;
argc--;
debug_flag = 1;
acct_flag = 0;
spawn_flag = 1;
#ifndef OS2
radacct_dir = RADACCT_DIR;
radius_dir = RADIUS_DIR;
#else
sprintf(work_dir,"%s%s",getenv("ETC"),RADIUS_DIR);
_abspath(radius_dir_hold,work_dir,256);
sprintf(work_dir,"%s%s",getenv("ETC"),RADACCT_DIR);
_abspath(radacct_dir_hold,work_dir,256);
radius_dir = radius_dir_hold;
radacct_dir = radacct_dir_hold;
#endif
signal(SIGHUP, sig_hup);
signal(SIGINT, sig_fatal);
signal(SIGQUIT, sig_fatal);
signal(SIGILL, sig_fatal);
// signal(SIGTRAP, sig_fatal);
// signal(SIGIOT, sig_fatal);
signal(SIGFPE, sig_fatal);
signal(SIGTERM, sig_fatal);
signal(SIGCHLD, sig_cleanup);
while(argc) {
if(**argv != '-') {
usage();
}
argval = *(*argv + 1);
argc--;
argv++;
switch(argval) {
case 'a':
if(argc == 0) {
usage();
}
radacct_dir = *argv;
argc--;
argv++;
DEBUG("diff acct dir\n");
break;
case 'd':
if(argc == 0) {
usage();
}
radius_dir = *argv;
argc--;
argv++;
DEBUG("diff radius dir\n");
break;
case 's': /* Single process mode */
spawn_flag = 0;
acct_flag = 1;
DEBUG("Single process mode\n");
break;
case 'v':
version();
break;
case 'x':
debug_flag = 1;
DEBUG("Debug mode\n");
break;
case 'i':
acct_flag = 1;
sockfd = -1;
DEBUG("Accounting spawn process\n");
break;
default:
usage();
break;
}
}
/* Initialize the dictionary */
if(dict_init() != 0) {
exit(-1);
}
DEBUG("dict_init complete\n");
/* Initialize Configuration Values */
if(config_init() != 0) {
exit(-1);
}
DEBUG("config_init complete\n");
if ( sockfd != -1 ) {
svp = getservbyname ("radius", "udp");
if (svp == (struct servent *) 0) {
fprintf (stderr, "%s: No such service: radius/udp\n", progname);
exit(-1);
}
lport = (u_short) svp->s_port;
sockfd = socket (AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
(void) perror ("auth socket");
exit(-1);
}
sin = (struct sockaddr_in *) & salocal;
memset ((char *) sin, '\0', sizeof (salocal));
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = INADDR_ANY;
sin->sin_port = lport;
result = bind (sockfd, & salocal, sizeof (*sin));
if (result < 0) {
(void) perror ("auth bind");
exit(-1);
}
DEBUG("Author socket complete\n");
}
/*
* Open Accounting Socket.
*/
svp = getservbyname ("radacct", "udp");
if (svp == (struct servent *) 0) {
fprintf (stderr, "%s: No such service: %s/%s\n",
progname, "radacct", "udp");
exit(-1);
}
//do not delete: lport = htons(ntohs(lport) +1);
lport = (u_short) svp->s_port;
acctfd = socket (AF_INET, SOCK_DGRAM, 0);
if (acctfd < 0) {
(void) perror ("acct socket");
exit(-1);
}
sin = (struct sockaddr_in *) & salocal;
memset ((char *) sin, '\0', sizeof (salocal));
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = INADDR_ANY;
sin->sin_port = lport;
result = bind (acctfd, & salocal, sizeof (*sin));
if (result < 0) {
(void) perror ("acct bind");
exit(-1);
}
DEBUG("Radacct socket complete\n");
/*
* Disconnect from session
*/
#ifndef OS2
if(debug_flag == 0) {
pid = fork();
if(pid < 0) {
fprintf(stderr, "%s: Couldn't fork\n", progname);
exit(-1);
}
if(pid > 0) {
exit(0);
}
}
#endif
/*
* Disconnect from tty
*/
for (t = 32; t >= 3; t--) {
if(t != sockfd && t != acctfd) {
close(t);
}
}
#if !defined(M_UNIX)
/*
* Open system console as stderr
*/
cons = open("/dev/console", O_WRONLY | O_NOCTTY);
if(cons != 2) {
dup2(cons, 2);
close(cons);
}
#endif
/*
* If we are able to spawn processes, we will start a child
* to listen for Accounting requests. If not, we will
* listen for them ourself.
*/
if( spawn_flag && !acct_flag ) {
#ifndef OS2
acct_pid = fork();
#else
acct_pid = spawnv(P_NOWAIT,nargv[0],nargv);
/* acct_pid = spawnl(P_NOWAIT,argv[0],argv[0],"-x","-i",(char *)0); */
#endif
DEBUG("Accounting Spawned\n");
if(acct_pid < 0) {
fprintf(stderr, "%s: Couldn't fork\n", progname);
exit(-1);
}
if(acct_pid > 0) {
close(acctfd);
acctfd = -1;
}
else {
if ( sockfd != -1 )
close(sockfd);
sockfd = -1;
}
}
/*
* Receive user requests
*/
sin = (struct sockaddr_in *) & saremote;
DEBUG("Ready to receive user requests\n");
for(;;) {
FD_ZERO(&readfds);
if(sockfd >= 0) {
FD_SET(sockfd, &readfds);
}
if(acctfd >= 0) {
FD_SET(acctfd, &readfds);
}
status = select(32, &readfds, NULL, NULL, NULL);
if(status == -1) {
if (errno == EINTR)